var GameEntity = require('js/gameEntity').GameEntity;
var gamejs = require('gamejs');

/**
 * ENEMY : an object representing an enemy.
 */

/**
 * Creates an enemy
 *
 * @param {Match} match The match were this enemy will live
 * @param {[number, number]} coords The enemy's position, in format [x, y].
 * @param {Number} level The Enemy level [default 0]
 *
 * @extends Sprite
 * @constructor
 */
var Enemy = exports.Enemy = function(match, coords, level) {
	// Call the GameEntity constructor
	Enemy.superConstructor.call(this, match, coords, Enemy.UPGRADE_LIST,
		false, level
	);
	// Pathfinding stuff
	this.path = [];
	this.pathIndex = 0;
	// Health informations (used to draw the lifebar)
	this.fullHealth = this.getLevelSettings().health;
	this.health = this.fullHealth;
	// Detected flag
	this.detected = false;
	// Sets imaga Opacity
	this.alpha = 40;
	this.image.setAlpha(1 - this.alpha / 100);
};

/**
 * Extending GameEntity with Enemy
 */
gamejs.utils.objects.extend(Enemy, GameEntity);

/**
 * List of available levels
 *
 * Each level must have the following properties (in addition to the
 * GameEntity's ones):
 *    - detectedImange: Image to use when Enemy is detected
 *    - health: HP of this Enemy
 *    - speed: movement speed in pixels/s
 *    - visibilityTime: when detected the Enemy is visible for this time [ms]
 *    - killScore: score awarded to the player for killing the enemy
 *    - killCredit: credits awarded to the player for killing the enemy
 */
Enemy.UPGRADE_LIST = [
	// Level 0
	{ image: IMAGE_ROOT + "enemy.png",
		detectedImage: IMAGE_ROOT + "enemy_detected.png",
		health: 1, speed: 30, visibilityTime: 1500, killScore: 10,
		killCredit: 5
	},
	// Level 1
	{ image: IMAGE_ROOT + "enemy.png",
		detectedImage: IMAGE_ROOT + "enemy_detected.png",
		health: 5, speed: 40, visibilityTime: 1200, killScore: 20,
		killCredit: 8
	}
];

/**
 * Subtracts health points, and kills the enemy if health reaches 0
 *
 * @param {number} hitRate The amount of health to subtract
 */
Enemy.prototype.hit = function(hitRate) {
	this.health -= hitRate;
	if(this.health <= 0) {
		this.health = 0;  // Health can't be negative
		this.getMatch().changeScore(this.getLevelSettings().killScore);
		this.getMatch().changeCredit(this.getLevelSettings().killCredit);
		this.kill();
	}
};

/**
 * Set the enemy detected for time specified in the enemy.visibilityTime
 *
 * @param {boolean} detected true to make the enemy visible, false
 *        to make it invisible
 */
Enemy.prototype.setDetected = function(detected) {
	if (detected){
		// if detected, changes the image with the visible one
		this.detected = this.getLevelSettings().visibilityTime;
		this.image = gamejs.image.load(this.getLevelSettings().detectedImage);
	}
	else{
		this.detected = 0;
	}
};

/**
 * Return detected flag
 *
 * @return {boolean} true if enemy is detected, false otherwise
 */
Enemy.prototype.isDetected = function() {
	return this.detected > 0;
};

/**
 * Updates the position of the Enemy
 */
Enemy.prototype.update = function(msDuration) {
	this.rect.moveIp( -this.getLevelSettings().speed * (msDuration/1000), 0);

	if(this.detected > 0) {
		// if is detected decreases the visibility counter
		this.detected -= msDuration;
		if (this.detected <= 0){
			// when the visibility counter fades to 0, returns the enemy
			// image in a non detected status
			this.updateImage();
			this.image.setAlpha(1 - this.alpha / 100);
		}
	}
};

/**
 * Overwrites sprite's Draw method
 */
Enemy.prototype.draw = function(surface) {
	// Draws the enemy
	var letfCorner = this.rect.topleft;
	surface.blit(this.image, letfCorner);
	
	// Draws the life-bar over the enemy image if detected
	var lifeStart = [letfCorner[0] + 4, letfCorner[1] - 4];
	var lifeEnd = [
		lifeStart[0] + Math.round(20 * this.health / this.fullHealth),
		lifeStart[1]
	];
	if(this.isDetected()) {
		gamejs.draw.line(surface, '#adff2f', lifeStart, lifeEnd, 2);
	}
};